package net.wofly.cashier.preorder.service.impl;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.transaction.Transactional;

import net.wofly.cashier.order.domain.Order;
import net.wofly.cashier.order.domain.OrderContent;
import net.wofly.cashier.order.service.ICashierOrderService;
import net.wofly.cashier.order.util.OrderStatus;
import net.wofly.cashier.order.util.OrderType;
import net.wofly.cashier.preorder.domain.BookMeal;
import net.wofly.cashier.preorder.domain.BookMealContent;
import net.wofly.cashier.preorder.repository.BookMealRepository;
import net.wofly.cashier.preorder.service.IBookMealContentService;
import net.wofly.cashier.preorder.service.IBookMealService;
import net.wofly.cashier.preorder.util.BookMealStatus;
import net.wofly.common.condition.Condition;
import net.wofly.common.condition.ConditionRelate;
import net.wofly.common.condition.FilterCondition;
import net.wofly.common.condition.Operation;
import net.wofly.common.persistence.PageWrapper;
import net.wofly.common.util.Identities;
import net.wofly.common.util.PageHelper;
import net.wofly.framework.util.ResultCode;
import net.wofly.framework.util.ReturnBean;
import net.wofly.sale.order.domain.PayInfo;
import net.wofly.sale.order.service.IPayInfoService;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

/**
 * @author siqingwei
 */
@Service("iBookMealService")
@Transactional
public class BookMealServiceImpl implements IBookMealService {

	@Autowired
	BookMealRepository bookMealRepository;
	@Autowired
	IBookMealContentService iBookMealContentService;
	@Autowired
	IPayInfoService iPayInfoService;
	@Autowired
    ICashierOrderService iCashierOrderService;

	@Override
	public BookMeal save(BookMeal entity) {
		return bookMealRepository.save(entity);
	}

	@Override
	public void delete(BookMeal entity) {
		bookMealRepository.delete(entity);
	}

	@Override
	public void delete(String key) {
		bookMealRepository.delete(key);
	}

	@Override
	public BookMeal findOne(String key) {
		return bookMealRepository.findOne(key);
	}

	@Override
	public List<BookMeal> save(List<BookMeal> entityList) {
		return (List<BookMeal>) bookMealRepository.save(entityList);
	}
	
	@Override
	public BookMeal findByTableIDAndStatusAndBookMealTimeBetween(
			String tableID, Integer status, Long startTime, Long endTime) {
		return bookMealRepository.findByTableIDAndStatusAndBookMealTimeBetween(tableID,status,startTime,endTime);
	}
	
	@Override
	public ReturnBean<BookMeal> addBookMeal(BookMeal bookMeal) {
		bookMeal.setBookMealID(Identities.uuid2());
		bookMeal.setModifyDate(System.currentTimeMillis());
		bookMeal.setBookTime(System.currentTimeMillis());

		List<BookMealContent> bookMealContentList = new ArrayList<>();
		int totalAmount = 0;
		for (BookMealContent entity : bookMeal.getBookMealContentList()) {
			entity.setBookMealContentID(Identities.uuid2());
			entity.setBookMealID(bookMeal.getBookMealID());
			entity.setModifyDate(System.currentTimeMillis());
			entity.setAmount(entity.getNum() * entity.getPrice());
			bookMealContentList.add(entity);
			totalAmount += entity.getAmount();
		}

		bookMeal.setAmount(totalAmount);
		ReturnBean<BookMeal> returnBean = saveBookMeal(bookMeal);
		iBookMealContentService.save(bookMealContentList);
		return returnBean;
	}

	public ReturnBean<BookMeal> saveBookMeal(BookMeal bookMeal) {
		String dayStartTimeStr = DateFormatUtils.format(new Date(bookMeal.getBookMealTime()), "yyyy-MM-dd 00:00:00");
		String dayEndTimeStr = DateFormatUtils.format(new Date(bookMeal.getBookMealTime()), "yyyy-MM-dd 23:59:59");
		try {
			Date dayStartTime = DateUtils.parseDate(dayStartTimeStr, "yyyy-MM-dd 00:00:00");
			Date dayEndTime = DateUtils.parseDate(dayEndTimeStr, "yyyy-MM-dd 23:59:59");
			Integer reservationNo = bookMealRepository.findByBookMealTimeBetween(dayStartTime.getTime(), dayEndTime.getTime());
			if (reservationNo == null) {
				bookMeal.setBookMealNo(1);
			} else {
				bookMeal.setBookMealNo(reservationNo + 1);
			}

			return new ReturnBean<>(ResultCode.SUCCESS, "新增预购成功！", bookMealRepository.save(bookMeal));
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return new ReturnBean<>(ResultCode.ERROR_SERVICE, "业务数据错误！");
	}

	@Override
	public ReturnBean<String> cancelBookMeal(String bookMealID, String customer) {
		BookMeal bookMeal = bookMealRepository.findOne(bookMealID);
		if (bookMeal == null) {
			return new ReturnBean<>(ResultCode.ERROR_SERVICE, "数据不存在，不能取消！");
		}

		Long currentTime = System.currentTimeMillis();

		if (bookMeal.getPayFlag() == 0) {
			if (!bookMeal.getCustomerUserID().equals(customer)) {
				return new ReturnBean<>(ResultCode.ERROR_SERVICE, "此预购订单不是您的, 不能取消！");
			}
			bookMeal.setStatus(BookMealStatus.订单未付款主动取消.getValue());
			bookMeal.setModifyDate(currentTime);
			bookMealRepository.save(bookMeal);
			return new ReturnBean<>(ResultCode.SUCCESS, "取消预购成功！");
		} else {
			if (bookMeal.getBookMealTime() - currentTime > 24 * 60 * 60 * 1000) {
				if (!bookMeal.getCustomerUserID().equals(customer)) {
					return new ReturnBean<>(ResultCode.ERROR_SERVICE, "此预购订单不是您的, 不能取消！");
				}
				bookMeal.setStatus(BookMealStatus.订单己付款主动取消.getValue());
				bookMeal.setModifyDate(currentTime);
				bookMealRepository.save(bookMeal);
				return new ReturnBean<>(ResultCode.SUCCESS, "取消预购成功！");
			} else {
				return new ReturnBean<>(ResultCode.ERROR_SERVICE, "在离就餐时间24小时内, 不能取消预购！");
			}
		}
	}

	@Override
	public ReturnBean<PageWrapper<BookMeal>> getAllBookMeal(Integer pageNum, Integer pageSize, String employeeID, Long mealTime, Integer status) {
		Condition condition = new Condition();
		List<FilterCondition> filterConditionList = new ArrayList<>();
		if (mealTime != null && mealTime != -1) {
			String dayStartTimeStr = DateFormatUtils.format(new Date(mealTime), "yyyy-MM-dd 00:00:00");
			String dayEndTimeStr = DateFormatUtils.format(new Date(mealTime), "yyyy-MM-dd 23:59:59");

			try {
				Date dayStartTime = DateUtils.parseDate(dayStartTimeStr, "yyyy-MM-dd 00:00:00");
				Date dayEndTime = DateUtils.parseDate(dayEndTimeStr, "yyyy-MM-dd 23:59:59");
				filterConditionList.add(new FilterCondition(String.valueOf(dayStartTime.getTime()), "bookMealTime", ConditionRelate.and.name(), Operation.ge.name(), 1));
				filterConditionList.add(new FilterCondition(String.valueOf(dayEndTime.getTime()), "bookMealTime", ConditionRelate.and.name(), Operation.le.name(), 1));
			} catch (ParseException e) {
				e.printStackTrace();

				return new ReturnBean<>(ResultCode.ERROR_SERVICE, "日期转换失败！");
			}
		}

		if (status != null && status != -1) {
			filterConditionList.add(new FilterCondition(String.valueOf(status), "status", ConditionRelate.and.name(), Operation.eq.name(), 2));
		}

		condition.setFilterCondition(filterConditionList);
		// 获得分页对象pageable，并且在pageable中页码是从0开始，设定按照sortType升序排列
		Pageable pageable = new PageRequest(pageNum - 1, pageSize);
		Page<BookMeal> page = bookMealRepository.findAll(condition.getSpecification(), pageable);
		return new ReturnBean<>(ResultCode.SUCCESS, "获取所有预约记录成功！", PageHelper.toPage(page));
	}

	@Override
	public ReturnBean<PageWrapper<BookMeal>> getMyBookMeal(Integer pageNum, Integer pageSize, String customer, Long mealTime, Integer status) {
		Condition condition = new Condition();
		List<FilterCondition> filterConditionList = new ArrayList<>();
		if (mealTime != null && mealTime != -1) {
			String dayStartTimeStr = DateFormatUtils.format(new Date(mealTime), "yyyy-MM-dd 00:00:00");
			String dayEndTimeStr = DateFormatUtils.format(new Date(mealTime), "yyyy-MM-dd 23:59:59");

			try {
				Date dayStartTime = DateUtils.parseDate(dayStartTimeStr, "yyyy-MM-dd 00:00:00");
				Date dayEndTime = DateUtils.parseDate(dayEndTimeStr, "yyyy-MM-dd 23:59:59");
				filterConditionList.add(new FilterCondition(String.valueOf(dayStartTime.getTime()), "bookMealTime", ConditionRelate.and.name(), Operation.ge.name(), 1));
				filterConditionList.add(new FilterCondition(String.valueOf(dayEndTime.getTime()), "bookMealTime", ConditionRelate.and.name(), Operation.le.name(), 1));
			} catch (ParseException e) {

				e.printStackTrace();
				return new ReturnBean<>(ResultCode.ERROR_SERVICE, "日期转换失败！");
			}
		}

		if (status != null && status != -1) {
			filterConditionList.add(new FilterCondition(String.valueOf(status), "status", ConditionRelate.and.name(), Operation.eq.name(), 2));
		}

		filterConditionList.add(new FilterCondition(customer, "customer", ConditionRelate.and.name(), Operation.eq.name(), 3));

		condition.setFilterCondition(filterConditionList);
		// 获得分页对象pageable，并且在pageable中页码是从0开始，设定按照sortType升序排列
		Pageable pageable = new PageRequest(pageNum - 1, pageSize);
		Page<BookMeal> page = bookMealRepository.findAll(condition.getSpecification(), pageable);
		return new ReturnBean<>(ResultCode.SUCCESS, "获取所有预约记录成功！", PageHelper.toPage(page));
	}

	@Override
	public ReturnBean<BookMeal> modifyMealTime(String bookMealID, String customer, String name, String mobile, Long mealTime) {
		BookMeal bookMeal = bookMealRepository.findOne(bookMealID);
		if (bookMeal == null) {
			return new ReturnBean<>(ResultCode.ERROR_SERVICE, "数据不存在，不能修改！");
		}

		if (!bookMeal.getCustomerUserID().equals(customer)) {
			return new ReturnBean<>(ResultCode.ERROR_SERVICE, "此预购订单不是您的, 不能修改！");
		}

		bookMeal.setName(name);
		bookMeal.setMobile(mobile);
		bookMeal.setBookMealTime(mealTime);

		ReturnBean<BookMeal> returnBean = this.saveBookMeal(bookMeal);
		returnBean.setMsg("修改就餐时间成功");
		return returnBean;
	}

	@Override
	public ReturnBean<String> payBookMeal(String bookMealID, String customer, Double num) {
		BookMeal bookMeal = bookMealRepository.findOne(bookMealID);
		if (bookMeal == null) {
			return new ReturnBean<>(ResultCode.ERROR_SERVICE, "数据不存在！");
		}

		if (!bookMeal.getCustomerUserID().equals(customer)) {
			return new ReturnBean<>(ResultCode.ERROR_SERVICE, "此预购订单不是您的！");
		}

		bookMeal.setStatus(BookMealStatus.订单己付款.getValue());
		bookMeal.setModifyDate(System.currentTimeMillis());
		bookMealRepository.save(bookMeal);

		PayInfo payInfo = new PayInfo();
		payInfo.setAmount(num);
		payInfo.setPayInfoID(Identities.uuid2());
		payInfo.setPayTime(System.currentTimeMillis());

		iPayInfoService.save(payInfo);

		return new ReturnBean<>(ResultCode.SUCCESS, "付款成功！");
	}

	@Override
	public ReturnBean<Order> repast(String bookMealID, String employeeID) {
		BookMeal bookMeal = bookMealRepository.findOne(bookMealID);
		if (bookMeal == null) {
			return new ReturnBean<>(ResultCode.ERROR_SERVICE, "数据不存在！");
		}

		bookMeal.setStatus(BookMealStatus.己就餐.getValue());
		bookMeal.setMealTime(System.currentTimeMillis());
		bookMeal.setModifyDate(System.currentTimeMillis());
		bookMealRepository.save(bookMeal);

		Order order = new Order();
		order.setTableID(bookMeal.getTableID());
		List<BookMealContent> bookMealContentList = iBookMealContentService.findByBookMealID(bookMealID);
		List<OrderContent> orderContents = new ArrayList<>();
		PayInfo payInfo = null;
		if (bookMeal.getPayFlag() == 1) {
			payInfo = iPayInfoService.findByOrderIDOrderByPayTimeDesc(bookMealID) ;
		}
		for (BookMealContent bookMealContent : bookMealContentList) {
			OrderContent orderContent = new OrderContent();
			orderContent.setCommodityID(bookMealContent.getCommodityID());
			orderContent.setNum(bookMealContent.getNum());
			orderContent.setPayFlag(bookMeal.getPayFlag());
			if (bookMeal.getPayFlag() == 1) {
				orderContent.setPayInfoID(payInfo.getPayInfoID());
			}
			//状态0为下单 1为己上菜 ；-1为取消
			orderContent.setStatus(0);

			orderContents.add(orderContent);
		}

		order.setOrderContents(orderContents);
		order.setOrderStatus(OrderStatus.己结帐.getValue());
		order.setOrderType(OrderType.预购.getValue());
		order.setRelationID(bookMealID);

		return iCashierOrderService.placeOrder(order, 1);
	}

	@Override
	public ReturnBean<BookMeal> verifyCancelBookMeal(String bookMealID, String employeeID) {
		BookMeal bookMeal = bookMealRepository.findOne(bookMealID);
		if (bookMeal == null) {
			return new ReturnBean<>(ResultCode.ERROR_SERVICE, "数据不存在！");
		}

		bookMeal.setStatus(BookMealStatus.订单己付款取消确认.getValue());
		bookMeal.setModifyDate(System.currentTimeMillis());
		bookMealRepository.save(bookMeal);

		return new ReturnBean<>(ResultCode.SUCCESS, "取消预定就餐确认！");
	}
}
